//
//  LREmoticon.swift
//  表情键盘
//
//  Created by 雷路荣 on 15/12/28.
//  Copyright © 2015年 leilurong. All rights reserved.
//

import UIKit
/**
 *  表情模型
 */
class LREmoticon: NSObject {
    ///表情包文件名称
    var id: String?
    ///表情名称，用于网络传输
    var chs: String?
    ///表情图片名称
    var png: String? {
        didSet{
            // 当kvc设置png时,来拼接完整地图片路径
            // 完整地图片路径 = bundlePath + id + 图片名称  注意加 ！拆包不然路径含有@optional
            pngPath = LREmoticonPackge.bundlePath + "/\(id!)" + "/\(png!)"
            //print("pngPath = \(pngPath)")
        }
    }
    /// 自定义表情图片的完整路径
    var pngPath: String?
    /// code用于显示emoji表情
    var code: String? {
        didSet{
            // kvc设置code之后,将code转成emoji表情
            // 创建扫描器
            let scanner = NSScanner(string: code!)
            // 扫描  result: UnsafeMutablePointer<UInt32>: 需要一个 UInt32类型的可变指针
            var result: UInt32 = 0
            scanner.scanHexInt(&result)
            //转成字符串
            let scalar = UnicodeScalar(result)
            let c = Character(scalar)
            emoji = String(c)
        }
    }
    /// 自定义emoji的字符串
    var emoji: String?
    
    /// 表情的使用次数,使用次数多的会显示在最近表情包的最前面
    var times = 0
    
    /// true 是删除按钮，false是空白按钮
    var removeEmoticon = false
    /// 模型显示删除按钮和空白表情,true 是删除按钮, false 是空白按钮
    init(removeEmoticon: Bool) {
        self.removeEmoticon = removeEmoticon
        super.init()
    }
    
    /// 字典转模型
    init(id: String?, dict: [String: AnyObject]) {
        super.init()
        self.id = id
        // 使用KVC赋值
        setValuesForKeysWithDictionary(dict)
    }
    // 字典的key在模型中找不到对应的属性
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {}
    // 对象打印方法
    override var description: String {
        return "\n\t\t表情模型:chs: \(chs), png: \(png), code: \(code)"
    }
    
    /**
    将表情模型转换成带图片的属性文本
    - parameter font: font
    - returns: 带图片的属性文本
    */
    func emoticonToAttrString(font: UIFont) -> NSAttributedString {
        //判断是否有图片
        if let pngPat = self.pngPath {
            // 图片路径有值
            // 2.1创建附件
            let attachment = LRTextAttachment()
            
            // 2.2给附件添加图片
            attachment.image = UIImage(contentsOfFile: pngPat)
            
            // 2.2.1设置附件的图片名称
            attachment.chs = chs
            
            // 2.2.2设置图片的bounds
            let w = font.lineHeight
            attachment.bounds = CGRect(x: 0, y: -(w * 0.2), width: w, height: w)
            
            // 2.3将附件转成可变的属性文本
            let attrText = NSMutableAttributedString(attributedString: NSAttributedString(attachment: attachment))
            
            // 2.3.2发现在图片后面连续添加图片,图片会变小.原因是附件缺少Font属性,给附件添加Font属性
            attrText.addAttribute(NSFontAttributeName, value: font, range: NSRange(location: 0, length: 1))
            
            return attrText
        }else{
            return NSAttributedString(string: "")
        }
    }
    
    /**
    根据表情名称找到对应的表情模型
    - parameter name: 表情名称
    - returns: 找到的表情模型
    */
    class func emoticonNameToEmoticon(name: String) -> LREmoticon? {
        // 记录下找到的模型
        var emoticon: LREmoticon?
        // 遍历所有的表情包
        for package in LREmoticonPackge.packages! {
            // 查找每个表情包里面所有模型,如果找到模型名称和name一样的就说明找到了对应的模型
            let array = package.emoticons.filter({ (emoticon) -> Bool in
                // true表示匹配到的数据
                return emoticon.chs == name
            })
            // 获取过滤后的数组中的第一个元素array里面可能没有元素
            let e = array.first
            if e != nil {
                // 说明在当前这个表情包里面找到了对应的表情模型
                emoticon = e
                // 注意: 一定要跳出循环
                break
            }
        }
        // 返回表情模型,有可能有,也有可能没有
        return emoticon
    }
    /*
    1.从微博内容中截取表情名称
    2.根据表情名称找到对应的表情模型 *
    3.将表情模型转成带表情图片的属性文本 *
    4.将微博内容中的表情名称替换成 带表情图片的属性文本
    */
    /// 将微博内容中的表情名称替换成表情图片
    class func stringToEmoticonText(text: String) -> NSAttributedString {
        // 1.从微博内容中截取表情名称
        // 定义查找规则,在正则表达式中[ ] 是有特殊含义的,需要转义
        let pattern = "\\[.*?\\]"// "[.*?]"
        // 创建正则表达式对象
        let regular = try! NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions.DotMatchesLineSeparators)
        // 使用正则表达式来匹配字符串
        let results = regular.matchesInString(text, options: NSMatchingOptions(rawValue: 0), range: NSRange(location: 0, length: text.characters.count))
        //获取匹配的结果数
        var count = results.count // 4: 3,2,1
        // 普通的文本是不能替换属性文本的, 将传入的微博内容整个转成属性文本
        let attrText = NSMutableAttributedString(string: text)
        // 从后面开始替换
        // 替换表情不能从前面往后面替换,从前面开始替换,后面的匹配结果位置会改变,后面的就不准了
        // 从后面往前面替换,因为替换后面的不会影响前面的范围
        while count > 0 {
            count--
            // 获取对应的结果
            let result = results[count]
            // 获取结果里面匹配到的范围
            //let number = result.numberOfRanges
            // 获取到结果中匹配的范围
            let range = result.rangeAtIndex(0)
            // 截取表情名称
            let emoticonName = (text as NSString).substringWithRange(range)
            //print("表情名称: \(emoticonName)")
            // 2.根据表情名称找到对应的表情模型 *
            if let emoticon = LREmoticon.emoticonNameToEmoticon(emoticonName) {
                // 3.将表情模型转成带表情图片的属性文本 *
                let attr = emoticon.emoticonToAttrString(UIFont.systemFontOfSize(14))
                // 4.将微博内容中的表情名称替换成 带表情图片的属性文本
                attrText.replaceCharactersInRange(range, withAttributedString: attr)
            }
        }
        // 微博里面的所有表情名称都替换好了
        return attrText
    }
}







































































